package generateur;

import modele.AbstractRegle;
import echiquier.Echiquier.Ligne;
import piece.AbstractPiece;
import piece.AbstractPiece.Type;

public class Regle {

    private Ligne ligne;
    private Ligne templigne;
    private final AbstractRegle<AbstractPiece> caseOccupee;
    private final AbstractRegle<AbstractPiece> regle1Case;
    private final AbstractRegle<AbstractPiece> regleDeplacement;
    private final AbstractRegle<AbstractPiece> regleRoiCavalier;
    private final AbstractRegle<AbstractPiece> estCeUnPion;
    private final  Generateur gen;

    public Regle(Generateur generateur) {
        gen = generateur;
        caseOccupee = new CaseOccupee();
        estCeUnPion = new EstCeUnPion();
        regleDeplacement = new RegleDeplacement();
        regleRoiCavalier = new RegleNCase();
        regle1Case = new Regle1Case();
    }

    public void getCaseOccupee(final AbstractPiece piece) {
        caseOccupee.SiAlorsSinon(piece);
    }

    public class CaseOccupee extends AbstractRegle<AbstractPiece> {

        @Override
        public boolean si(final AbstractPiece piece) {
            return piece != null;
        }

        @Override
        public void alors(final AbstractPiece piece) {
            estCeUnPion.SiAlorsSinon(piece);
        }

        @Override
        public void sinon(final AbstractPiece piece) {
        }
    }

    public class EstCeUnPion extends AbstractRegle<AbstractPiece> {

        @Override
        public boolean si(AbstractPiece piece) {
            return piece.type == Type.Pion;
        }

        @Override
        public void alors(AbstractPiece piece) {
            // regleDeplacementPion.SiAlorsSinon();
        }

        @Override
        public void sinon(AbstractPiece piece) {
            regleDeplacement.SiAlorsSinon(piece);
        }
    }

    public class RegleNCase extends AbstractRegle<AbstractPiece> {

        @Override
        public boolean si(AbstractPiece piece) {
            return piece.type != Type.Roi &&
                   piece.type != Type.Cavalier;
        }

        @Override
        public void alors(AbstractPiece piece) {
            gen.traitement();
        }

        @Override
        public void sinon(AbstractPiece piece) {
            regle1Case.SiAlorsSinon(piece);
        }
    }

    public class Regle1Case extends AbstractRegle<AbstractPiece> {

        @Override
        public boolean si(AbstractPiece piece) {
            if (templigne != ligne) {
                templigne = ligne;
                return true;
            } else {
                return false;
            }
        }

        @Override
        public void alors(AbstractPiece piece) {
            gen.traitement();
        }

        @Override
        public void sinon(AbstractPiece piece) {
        }
    }

    public class RegleDeplacement extends AbstractRegle<AbstractPiece> {

        @Override
        public boolean si(AbstractPiece piece) {
            ligne = gen.etat.LigneCourante();
            return piece.verifie(ligne);
        }

        @Override
        public void alors(AbstractPiece piece) {
            regleRoiCavalier.SiAlorsSinon(piece);
        }

        @Override
        public void sinon(AbstractPiece piece) {
        }
    }
}
